package com.core;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

public class EchoSeverZJH {
	private Selector selector;
	private ServerSocketChannel serverSocketChannel;
	private int port = 8000;
	private Charset charset = Charset.forName("GBK");
	private List<String> list = new ArrayList<>();
	private int num;
	
	public EchoSeverZJH(){
		try {
			selector = Selector.open();
			serverSocketChannel = ServerSocketChannel.open();
			serverSocketChannel.configureBlocking(false);
			serverSocketChannel.socket().setReuseAddress(true);
			serverSocketChannel.socket().bind(new InetSocketAddress(port));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		System.out.println("服务器开启成功... : " + new Date());
		list.add("一共有18018条航班数据");
		try (Scanner cin = new Scanner(new BufferedInputStream(new FileInputStream("copy")))) {
			String line = null;
			while(cin.hasNext()) {
				line = cin.nextLine();
				list.add(line);
			}
			list.add("no data");
		} catch (IOException e) {
			e.printStackTrace();
		}
		num = list.size();
		System.out.println("数据已准备好... : " + new Date());
	}

	public void service(){
		try {
			serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		} catch (ClosedChannelException e) {
			e.printStackTrace();
		}
		while (true) {
			//没有连接就会阻塞
			int n = 0;
			try {
				n = selector.select();
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (n == 0)
				continue;
			Set<SelectionKey> readkeys = selector.selectedKeys();
			Iterator<SelectionKey> iterator = readkeys.iterator();
			while (iterator.hasNext()) {
				SelectionKey key = iterator.next();
				if(!key.isValid()) {
					iterator.remove();
					continue;
				}
				if (key.isAcceptable()) {
					accept(key);
				}
				if (key.isWritable()) {
					send(key);
				}
				iterator.remove();
			}
		}
	}

	// 处理接收连接就绪事件
	private void accept(SelectionKey key){
		// 返回一个对象
		SocketChannel socketChannel;
		try {
			socketChannel = serverSocketChannel.accept();
			System.out.println("收到了客户端连接，来自 ： " + socketChannel.getRemoteAddress());
			socketChannel.configureBlocking(false);
			//注册到selector
			socketChannel.register(selector, SelectionKey.OP_WRITE, 0);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 处理写就绪事件
	private void send(SelectionKey key){
		SocketChannel socketChannel = (SocketChannel) key.channel();
		int index = (int)key.attachment();
		key.attach((index + 1) % num);
		String line = list.get(index);
		ByteBuffer outputBuffer = charset.encode(line + "\r\n");
		while (outputBuffer.hasRemaining()) {
			try {
				socketChannel.write(outputBuffer);
			} catch (IOException e) {
				key.cancel();
				try {
					System.out.println(socketChannel.getRemoteAddress() + "   断开连接----");
					socketChannel.socket().close();
					socketChannel.close();
					outputBuffer.clear();
					break;
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				e.printStackTrace();
			}
		}
		key.attach((index + 1) % num);
	}

	public static void main(String[] args){
		new EchoSeverZJH().service();
	}
}